gdk: Replace 'WITHDRAWN' state with async 'is-mapped' boolean
authorJonas Ådahl <jadahl@gmail.com>
Mon, 7 Dec 2020 17:18:38 +0000 (18:18 +0100)
committerJonas Ådahl <jadahl@gmail.com>
Mon, 7 Dec 2020 19:37:30 +0000 (20:37 +0100)
It was used by all surfaces to track 'is-mapped', but still part of the
GdkToplevelState, and is now replaced with a separate boolean in the
GdkSurface structure.

It also caused issues when a widget was unmapped, and due to that
unmapped a popover which hid its corresponding surface. When this
surface was hidden, it emitted a state change event, which would then go
back into GTK and queue a resize on popover widget, which would travel
back down to the widget that was originally unmapped, causing confusino
when doing future allocations.

To summarize, one should not hide widgets during allocation, and to
avoid this, make this new is-mapped boolean asynchronous when hiding a
surface, meaning the notification event for the changed mapped state
will be emitted in an idle callback. This avoids the above described
reentry issue.

17 files changed:
gdk/broadway/gdksurface-broadway.c
gdk/gdksurface.c
gdk/gdksurfaceprivate.h
gdk/gdktoplevel.c
gdk/gdktoplevel.h
gdk/macos/gdkmacossurface.c
gdk/wayland/gdksurface-wayland.c
gdk/win32/gdkevents-win32.c
gdk/win32/gdkmain-win32.c
gdk/win32/gdksurface-win32.c
gdk/x11/gdkdisplay-x11.c
gdk/x11/gdkdrag-x11.c
gdk/x11/gdkglcontext-x11.c
gdk/x11/gdksurface-x11.c
gtk/gtktooltipwindow.c
gtk/gtkwindow.c
tests/testgtk.c

index 30ba9ff51b62805e08df96204a02f9c0afe8e0a1..d44b2281f06d3120a91c421af9fb5dfaeedf1fb1 100644 (file)
@@ -601,7 +601,7 @@ gdk_broadway_surface_layout_popup (GdkSurface     *surface,
 static void
 show_popup (GdkSurface *surface)
 {
-  gdk_synthesize_surface_state (surface, GDK_TOPLEVEL_STATE_WITHDRAWN, 0);
+  gdk_surface_set_is_mapped (surface, TRUE);
   gdk_broadway_surface_show (surface, FALSE);
   gdk_surface_invalidate_rect (surface, NULL);
 }
@@ -1521,7 +1521,7 @@ show_surface (GdkSurface *surface)
   was_mapped = GDK_SURFACE_IS_MAPPED (surface);
 
   if (!was_mapped)
-    gdk_synthesize_surface_state (surface, GDK_TOPLEVEL_STATE_WITHDRAWN, 0);
+    gdk_surface_set_is_mapped (surface, TRUE);
 
   gdk_broadway_surface_show (surface, FALSE);
 
index 27b775982c08e7e27cd1f2a1c3863f2a06407e3c..012864479a65bf7895ee56f9ff9a3cb4f18fcf24 100644 (file)
@@ -114,6 +114,9 @@ static void update_cursor               (GdkDisplay *display,
 static void gdk_surface_set_frame_clock (GdkSurface      *surface,
                                          GdkFrameClock  *clock);
 
+static void gdk_surface_queue_set_is_mapped (GdkSurface *surface,
+                                             gboolean    is_mapped);
+
 
 static guint signals[LAST_SIGNAL] = { 0 };
 static GParamSpec *properties[LAST_PROP] = { NULL, };
@@ -472,7 +475,7 @@ gdk_surface_init (GdkSurface *surface)
 {
   /* 0-initialization is good for all other fields. */
 
-  surface->state = GDK_TOPLEVEL_STATE_WITHDRAWN;
+  surface->state = 0;
   surface->fullscreen_mode = GDK_FULLSCREEN_ON_CURRENT_MONITOR;
   surface->width = 1;
   surface->height = 1;
@@ -923,7 +926,10 @@ _gdk_surface_destroy_hierarchy (GdkSurface *surface,
 
   _gdk_surface_clear_update_area (surface);
 
-  surface->state |= GDK_TOPLEVEL_STATE_WITHDRAWN;
+  g_clear_handle_id (&surface->set_is_mapped_source_id, g_source_remove);
+  surface->is_mapped = FALSE;
+  surface->pending_is_mapped = FALSE;
+
   surface->destroyed = TRUE;
 
   surface_remove_from_pointer_info (surface, surface->display);
@@ -1696,14 +1702,7 @@ gdk_surface_hide (GdkSurface *surface)
 
   was_mapped = GDK_SURFACE_IS_MAPPED (surface);
 
-  if (GDK_SURFACE_IS_MAPPED (surface))
-    {
-      gdk_synthesize_surface_state (surface,
-                                    surface->state & ~GDK_TOPLEVEL_STATE_WITHDRAWN,
-                                    GDK_TOPLEVEL_STATE_WITHDRAWN);
-      surface->pending_unset_flags = 0;
-      surface->pending_set_flags = 0;
-    }
+  gdk_surface_queue_set_is_mapped (surface, FALSE);
 
   if (was_mapped)
     {
@@ -2614,7 +2613,6 @@ void
 gdk_surface_set_state (GdkSurface      *surface,
                        GdkToplevelState new_state)
 {
-  gboolean was_mapped, mapped;
   gboolean was_sticky, sticky;
   g_return_if_fail (GDK_IS_SURFACE (surface));
 
@@ -2626,20 +2624,15 @@ gdk_surface_set_state (GdkSurface      *surface,
    * inconsistent state to the user.
    */
 
-  was_mapped = GDK_SURFACE_IS_MAPPED (surface);
   was_sticky = GDK_SURFACE_IS_STICKY (surface);
 
   surface->state = new_state;
 
-  mapped = GDK_SURFACE_IS_MAPPED (surface);
   sticky = GDK_SURFACE_IS_STICKY (surface);
 
   if (GDK_IS_TOPLEVEL (surface))
     g_object_notify (G_OBJECT (surface), "state");
 
-  if (was_mapped != mapped)
-    g_object_notify_by_pspec (G_OBJECT (surface), properties[PROP_MAPPED]);
-
   if (was_sticky != sticky)
     g_object_notify (G_OBJECT (surface), "sticky");
 }
@@ -2673,12 +2666,73 @@ gdk_surface_apply_state_change (GdkSurface *surface)
   gdk_synthesize_surface_state (surface,
                                 surface->pending_unset_flags,
                                 surface->pending_set_flags);
-  if (surface->pending_unset_flags & GDK_TOPLEVEL_STATE_WITHDRAWN)
-    gdk_surface_invalidate_rect (surface, NULL);
   surface->pending_unset_flags = 0;
   surface->pending_set_flags = 0;
 }
 
+static gboolean
+set_is_mapped_idle (gpointer user_data)
+{
+  GdkSurface *surface = GDK_SURFACE (user_data);
+
+  surface->set_is_mapped_source_id = 0;
+
+  g_return_val_if_fail (surface->pending_is_mapped != surface->is_mapped,
+                        G_SOURCE_REMOVE);
+
+  surface->is_mapped = surface->pending_is_mapped;
+  if (surface->is_mapped)
+    gdk_surface_invalidate_rect (surface, NULL);
+
+  g_object_notify (G_OBJECT (surface), "mapped");
+
+  return G_SOURCE_REMOVE;
+}
+
+void
+gdk_surface_set_is_mapped (GdkSurface *surface,
+                           gboolean    is_mapped)
+{
+  gboolean was_mapped;
+
+  if (surface->pending_is_mapped != surface->is_mapped)
+    g_clear_handle_id (&surface->set_is_mapped_source_id, g_source_remove);
+
+  surface->pending_is_mapped = is_mapped;
+
+  was_mapped = surface->is_mapped;
+  surface->is_mapped = is_mapped;
+  if (surface->is_mapped)
+    gdk_surface_invalidate_rect (surface, NULL);
+
+  if (was_mapped != is_mapped)
+    g_object_notify (G_OBJECT (surface), "mapped");
+}
+
+static void
+gdk_surface_queue_set_is_mapped (GdkSurface *surface,
+                                 gboolean    is_mapped)
+{
+  if (surface->pending_is_mapped == is_mapped)
+    return;
+
+  surface->pending_is_mapped = is_mapped;
+
+  if (surface->is_mapped == surface->pending_is_mapped)
+    {
+      g_clear_handle_id (&surface->set_is_mapped_source_id, g_source_remove);
+    }
+  else
+    {
+      g_return_if_fail (!surface->set_is_mapped_source_id);
+
+      surface->set_is_mapped_source_id =
+        g_idle_add_full (G_PRIORITY_HIGH - 10,
+                         set_is_mapped_idle,
+                         surface, NULL);
+    }
+}
+
 static gboolean
 check_autohide (GdkEvent *event)
 {
index 4c879fc2cb63627829a1c9c01b4d3dba19d76ed3..27a3966fe75ea99548b720eac57dfe663ebec4c5 100644 (file)
@@ -44,6 +44,10 @@ struct _GdkSurface
   GdkSurface *parent;        /* for popups */
   GList *children;           /* popups */
 
+  guint set_is_mapped_source_id;
+  gboolean pending_is_mapped;
+  gboolean is_mapped;
+
   gpointer widget;
 
   int x;
@@ -167,12 +171,14 @@ struct _GdkSurfaceClass
 
 #define GDK_SURFACE_DESTROYED(d) (((GdkSurface *)(d))->destroyed)
 
-#define GDK_SURFACE_IS_MAPPED(surface) (((surface)->state & GDK_TOPLEVEL_STATE_WITHDRAWN) == 0)
-
+#define GDK_SURFACE_IS_MAPPED(surface) ((surface)->pending_is_mapped)
 
 void gdk_surface_set_state (GdkSurface      *surface,
                             GdkToplevelState  new_state);
 
+void gdk_surface_set_is_mapped (GdkSurface *surface,
+                                gboolean    is_mapped);
+
 GdkMonitor * gdk_surface_get_layout_monitor (GdkSurface      *surface,
                                              GdkPopupLayout  *layout,
                                              void           (*get_bounds) (GdkMonitor   *monitor,
index 4cff2bb3dd7bb66d4b9e9095e36c3fa5498f8472..13eb38cda1e3cb6f7bb9b9263941f0fbb23420d3 100644 (file)
@@ -123,7 +123,7 @@ gdk_toplevel_default_init (GdkToplevelInterface *iface)
       g_param_spec_flags ("state",
                           P_("State"),
                           P_("State"),
-                          GDK_TYPE_TOPLEVEL_STATE, GDK_TOPLEVEL_STATE_WITHDRAWN,
+                          GDK_TYPE_TOPLEVEL_STATE, 0,
                           G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
   g_object_interface_install_property (iface,
       g_param_spec_string ("title",
index 28402feb105b0b8fabd7a22efe38a47fb4f0cad3..fb293157104c8342d5a6e4bfeb04eeb96eedf2f0 100644 (file)
@@ -71,7 +71,6 @@ typedef enum
 
 /**
  * GdkToplevelState:
- * @GDK_TOPLEVEL_STATE_WITHDRAWN: the surface is not shown
  * @GDK_TOPLEVEL_STATE_MINIMIZED: the surface is minimized
  * @GDK_TOPLEVEL_STATE_MAXIMIZED: the surface is maximized
  * @GDK_TOPLEVEL_STATE_STICKY: the surface is sticky
@@ -98,23 +97,22 @@ typedef enum
  */
 typedef enum
 {
-  GDK_TOPLEVEL_STATE_WITHDRAWN        = 1 << 0,
-  GDK_TOPLEVEL_STATE_MINIMIZED        = 1 << 1,
-  GDK_TOPLEVEL_STATE_MAXIMIZED        = 1 << 2,
-  GDK_TOPLEVEL_STATE_STICKY           = 1 << 3,
-  GDK_TOPLEVEL_STATE_FULLSCREEN       = 1 << 4,
-  GDK_TOPLEVEL_STATE_ABOVE            = 1 << 5,
-  GDK_TOPLEVEL_STATE_BELOW            = 1 << 6,
-  GDK_TOPLEVEL_STATE_FOCUSED          = 1 << 7,
-  GDK_TOPLEVEL_STATE_TILED            = 1 << 8,
-  GDK_TOPLEVEL_STATE_TOP_TILED        = 1 << 9,
-  GDK_TOPLEVEL_STATE_TOP_RESIZABLE    = 1 << 10,
-  GDK_TOPLEVEL_STATE_RIGHT_TILED      = 1 << 11,
-  GDK_TOPLEVEL_STATE_RIGHT_RESIZABLE  = 1 << 12,
-  GDK_TOPLEVEL_STATE_BOTTOM_TILED     = 1 << 13,
-  GDK_TOPLEVEL_STATE_BOTTOM_RESIZABLE = 1 << 14,
-  GDK_TOPLEVEL_STATE_LEFT_TILED       = 1 << 15,
-  GDK_TOPLEVEL_STATE_LEFT_RESIZABLE   = 1 << 16
+  GDK_TOPLEVEL_STATE_MINIMIZED        = 1 << 0,
+  GDK_TOPLEVEL_STATE_MAXIMIZED        = 1 << 1,
+  GDK_TOPLEVEL_STATE_STICKY           = 1 << 2,
+  GDK_TOPLEVEL_STATE_FULLSCREEN       = 1 << 3,
+  GDK_TOPLEVEL_STATE_ABOVE            = 1 << 4,
+  GDK_TOPLEVEL_STATE_BELOW            = 1 << 5,
+  GDK_TOPLEVEL_STATE_FOCUSED          = 1 << 6,
+  GDK_TOPLEVEL_STATE_TILED            = 1 << 7,
+  GDK_TOPLEVEL_STATE_TOP_TILED        = 1 << 8,
+  GDK_TOPLEVEL_STATE_TOP_RESIZABLE    = 1 << 9,
+  GDK_TOPLEVEL_STATE_RIGHT_TILED      = 1 << 10,
+  GDK_TOPLEVEL_STATE_RIGHT_RESIZABLE  = 1 << 11,
+  GDK_TOPLEVEL_STATE_BOTTOM_TILED     = 1 << 12,
+  GDK_TOPLEVEL_STATE_BOTTOM_RESIZABLE = 1 << 13,
+  GDK_TOPLEVEL_STATE_LEFT_TILED       = 1 << 14,
+  GDK_TOPLEVEL_STATE_LEFT_RESIZABLE   = 1 << 15
 } GdkToplevelState;
 
 
index 705ae1d5ce136404e54ac4a26107d70338e677e5..5e528ca8e2916a96d5656307ad711cc561f40d63 100644 (file)
@@ -762,7 +762,7 @@ _gdk_macos_surface_show (GdkMacosSurface *self)
   was_mapped = GDK_SURFACE_IS_MAPPED (GDK_SURFACE (self));
 
   if (!was_mapped)
-    gdk_synthesize_surface_state (GDK_SURFACE (self), GDK_TOPLEVEL_STATE_WITHDRAWN, 0);
+    gdk_surface_set_is_mapped (GDK_SURFACE (self), TRUE);
 
   _gdk_macos_display_clear_sorting (GDK_MACOS_DISPLAY (GDK_SURFACE (self)->display));
 
index 9ce5669bacacb1e8818788756f0f5c504474ee2f..602d76b77369b17b02a26786d152aca817267dbe 100644 (file)
@@ -1602,7 +1602,7 @@ maybe_notify_mapped (GdkSurface *surface)
     return;
 
   if (!GDK_SURFACE_IS_MAPPED (surface))
-    gdk_surface_queue_state_change (surface, GDK_TOPLEVEL_STATE_WITHDRAWN, 0);
+    gdk_surface_set_is_mapped (surface, TRUE);
 }
 
 static void
index 1a50cdb5dd653275055397f164171fbf3e76b9f8..dbdcab2c43ef39e4c6ad4cdecc5131000c0d5c34 100644 (file)
@@ -2825,11 +2825,6 @@ gdk_event_translate (MSG *msg,
          set_bits = 0;
          unset_bits = 0;
 
-         if (IsWindowVisible (msg->hwnd))
-           unset_bits |= GDK_TOPLEVEL_STATE_WITHDRAWN;
-         else
-           set_bits |= GDK_TOPLEVEL_STATE_WITHDRAWN;
-
          if (IsIconic (msg->hwnd))
            set_bits |= GDK_TOPLEVEL_STATE_MINIMIZED;
          else
@@ -2840,6 +2835,7 @@ gdk_event_translate (MSG *msg,
          else
            unset_bits |= GDK_TOPLEVEL_STATE_MAXIMIZED;
 
+         gdk_surface_set_is_mapped (window, !!IsWindowVisible (msg->hwnd));
          gdk_synthesize_surface_state (window, unset_bits, set_bits);
 
          new_state = window->state;
index 73d0420011c5dbf048f9e89cb6bd019a2ac7b25d..6d4e44cfc779a3b3cb923948286f14378438d30d 100644 (file)
@@ -274,11 +274,6 @@ _gdk_win32_surface_state_to_string (GdkToplevelState state)
   if (state & GDK_TOPLEVEL_STATE_ ## x)                        \
     (bufp += sprintf (bufp, "%s" #x, s), s = "|")
 
-  /* For clarity, also show the complement of WITHDRAWN, i.e. "MAPPED" */
-  if (!(state & GDK_TOPLEVEL_STATE_WITHDRAWN))
-    (bufp += sprintf (bufp, "MAPPED"), s = "|");
-
-  BIT (WITHDRAWN);
   BIT (MINIMIZED);
   BIT (MAXIMIZED);
   BIT (STICKY);
index a7b1bda775f9fc59808b77f6d6043e40905f9a0c..263fcc6c60e466fe49d5ebdbd89de44539269741 100644 (file)
@@ -1006,9 +1006,7 @@ gdk_win32_surface_hide (GdkSurface *window)
                           _gdk_win32_surface_state_to_string (window->state)));
 
   if (GDK_SURFACE_IS_MAPPED (window))
-    gdk_synthesize_surface_state (window,
-                                0,
-                                GDK_TOPLEVEL_STATE_WITHDRAWN);
+    gdk_surface_set_is_mapped (window, FALSE);
 
   _gdk_surface_clear_update_area (window);
 
@@ -1262,7 +1260,7 @@ static void
 show_popup (GdkSurface *surface)
 {
   gdk_win32_surface_raise (surface);
-  gdk_synthesize_surface_state (surface, GDK_TOPLEVEL_STATE_WITHDRAWN, 0);
+  gdk_surface_set_is_mapped (surface, TRUE);
   show_window_internal (surface, FALSE, FALSE);
   gdk_surface_invalidate_rect (surface, NULL);
 }
@@ -4924,7 +4922,7 @@ show_surface (GdkSurface *surface)
   was_mapped = GDK_SURFACE_IS_MAPPED (surface);
 
   if (!was_mapped)
-    gdk_synthesize_surface_state (surface, GDK_TOPLEVEL_STATE_WITHDRAWN, 0);
+    gdk_surface_set_is_mapped (surface, TRUE);
 
   gdk_win32_surface_show (surface, FALSE);
 
index 31b06ea53fcdc1d508c4d054ecaaa18c6e75f0e2..4350f2eef80fea62a2fb4ed320c7adb8a6fe8be5 100644 (file)
@@ -566,7 +566,7 @@ gdk_check_edge_constraints_changed (GdkSurface *surface)
        * messing around with shifts, just make the passed value and GDK's
        * enum values match by shifting to the first tiled state.
        */
-      toplevel->edge_constraints = constraints[0] << 9;
+      toplevel->edge_constraints = constraints[0] << 8;
 
       XFree (constraints);
     }
index 8e40cab4471b590163e798cd65ca3b620f02f22b..606cef0f0cfbc298b7382e217161cfedcfa99c0e 100644 (file)
@@ -2036,7 +2036,7 @@ _gdk_x11_surface_drag_begin (GdkSurface         *surface,
   if (gdk_x11_surface_get_group (surface))
     gdk_x11_surface_set_group (x11_drag->ipc_surface, surface);
 
-  gdk_synthesize_surface_state (x11_drag->ipc_surface, GDK_TOPLEVEL_STATE_WITHDRAWN, 0);
+  gdk_surface_set_is_mapped (x11_drag->ipc_surface, TRUE);
   gdk_x11_surface_show (x11_drag->ipc_surface, FALSE);
 
   x11_drag->drag_surface = create_drag_surface (display);
index a3327734930525efcd1ffa9268c5c6d22289e3ec..d83ef6aaadd7142545a4406ee5c151ef694ba8ca 100644 (file)
@@ -463,7 +463,7 @@ on_surface_state_changed (GdkGLContext *context)
 {
   GdkSurface *surface = gdk_gl_context_get_surface (context);
 
-  if ((surface->state & GDK_TOPLEVEL_STATE_WITHDRAWN) == 0)
+  if (GDK_SURFACE_IS_MAPPED (surface))
     return;
 
   /* If we're about to withdraw the surface, then we don't care if the frame is
index 66803125637713e3e2b7eed66617198a90389a37..293134371e868f257bec024aa7de809d0af57e4f 100644 (file)
@@ -1401,7 +1401,7 @@ update_wm_hints (GdkSurface *surface,
 
   if (!force &&
       !toplevel->is_leader &&
-      surface->state & GDK_TOPLEVEL_STATE_WITHDRAWN)
+      !GDK_SURFACE_IS_MAPPED (surface))
     return;
 
   wm_hints.flags = StateHint | InputHint;
@@ -1608,9 +1608,7 @@ gdk_x11_surface_withdraw (GdkSurface *surface)
   if (!surface->destroyed)
     {
       if (GDK_SURFACE_IS_MAPPED (surface))
-        gdk_synthesize_surface_state (surface,
-                                     0,
-                                     GDK_TOPLEVEL_STATE_WITHDRAWN);
+        gdk_surface_set_is_mapped (surface, FALSE);
 
       g_assert (!GDK_SURFACE_IS_MAPPED (surface));
       XWithdrawWindow (GDK_SURFACE_XDISPLAY (surface),
@@ -1852,7 +1850,7 @@ static void
 show_popup (GdkSurface *surface)
 {
   gdk_x11_surface_raise (surface);
-  gdk_synthesize_surface_state (surface, GDK_TOPLEVEL_STATE_WITHDRAWN, 0);
+  gdk_surface_set_is_mapped (surface, TRUE);
   gdk_x11_surface_show (surface, FALSE);
   gdk_surface_invalidate_rect (surface, NULL);
 }
@@ -5116,7 +5114,7 @@ gdk_x11_toplevel_present (GdkToplevel       *toplevel,
   gdk_surface_request_layout (surface);
 
   if (!was_mapped)
-    gdk_synthesize_surface_state (surface, GDK_TOPLEVEL_STATE_WITHDRAWN, 0);
+    gdk_surface_set_is_mapped (surface, TRUE);
 
   gdk_x11_surface_show (surface, was_mapped);
 
@@ -5287,7 +5285,7 @@ gdk_x11_drag_surface_present (GdkDragSurface *drag_surface,
   GdkSurface *surface = GDK_SURFACE (drag_surface);
 
   gdk_x11_surface_toplevel_resize (surface, width, height);
-  gdk_synthesize_surface_state (surface, GDK_TOPLEVEL_STATE_WITHDRAWN, 0);
+  gdk_surface_set_is_mapped (surface, TRUE);
   gdk_x11_surface_show (surface, FALSE);
   gdk_surface_invalidate_rect (surface, NULL);
 
index 55c6a882d16cd58715a51b6ffb7c3b35d972c220..a3dbf83db4dcf41e913ab42221d654b5ef93f774 100644 (file)
@@ -47,7 +47,6 @@ struct _GtkTooltipWindow
   GdkSurface *surface;
   GskRenderer *renderer;
 
-  GdkToplevelState state;
   GtkWidget *relative_to;
   GdkRectangle rect;
   GdkGravity rect_anchor;
@@ -178,21 +177,12 @@ gtk_tooltip_window_native_init (GtkNativeInterface *iface)
 }
 
 static void
-surface_state_changed (GtkWidget *widget)
+mapped_changed (GdkSurface *surface,
+                GParamSpec *pspec,
+                GtkWidget  *widget)
 {
-  GtkTooltipWindow *window = GTK_TOOLTIP_WINDOW (widget);
-  GdkToplevelState new_surface_state;
-  GdkToplevelState changed_mask;
-
-  new_surface_state = gdk_toplevel_get_state (GDK_TOPLEVEL (window->surface));
-  changed_mask = new_surface_state ^ window->state;
-  window->state = new_surface_state;
-
-  if (changed_mask & GDK_TOPLEVEL_STATE_WITHDRAWN)
-    {
-      if (window->state & GDK_TOPLEVEL_STATE_WITHDRAWN)
-        gtk_widget_hide (widget);
-    }
+  if (!gdk_surface_get_mapped (surface))
+    gtk_widget_hide (widget);
 }
 
 static gboolean
@@ -224,7 +214,7 @@ gtk_tooltip_window_realize (GtkWidget *widget)
 
   gdk_surface_set_widget (window->surface, widget);
 
-  g_signal_connect_swapped (window->surface, "notify::state", G_CALLBACK (surface_state_changed), widget);
+  g_signal_connect (window->surface, "notify::mapped", G_CALLBACK (mapped_changed), widget);
   g_signal_connect (window->surface, "render", G_CALLBACK (surface_render), widget);
   g_signal_connect (window->surface, "event", G_CALLBACK (surface_event), widget);
 
@@ -247,7 +237,7 @@ gtk_tooltip_window_unrealize (GtkWidget *widget)
   gsk_renderer_unrealize (window->renderer);
   g_clear_object (&window->renderer);
 
-  g_signal_handlers_disconnect_by_func (window->surface, surface_state_changed, widget);
+  g_signal_handlers_disconnect_by_func (window->surface, mapped_changed, widget);
   g_signal_handlers_disconnect_by_func (window->surface, surface_render, widget);
   g_signal_handlers_disconnect_by_func (window->surface, surface_event, widget);
   gdk_surface_set_widget (window->surface, NULL);
index 176ae22bf59eb1638499d6f52356910504a86f9f..7e22e4bcbef73c5a999ae4245338b04459068cd9 100644 (file)
@@ -1503,7 +1503,7 @@ gtk_window_init (GtkWindow *window)
   priv->decorated = TRUE;
   priv->display = gdk_display_get_default ();
 
-  priv->state = GDK_TOPLEVEL_STATE_WITHDRAWN;
+  priv->state = 0;
 
   priv->deletable = TRUE;
   priv->startup_id = NULL;
@@ -4165,6 +4165,7 @@ gtk_window_realize (GtkWidget *widget)
     priv->renderer = gsk_renderer_new_for_surface (surface);
 
   g_signal_connect_swapped (surface, "notify::state", G_CALLBACK (surface_state_changed), widget);
+  g_signal_connect_swapped (surface, "notify::mapped", G_CALLBACK (surface_state_changed), widget);
   g_signal_connect (surface, "render", G_CALLBACK (surface_render), widget);
   g_signal_connect (surface, "event", G_CALLBACK (surface_event), widget);
   g_signal_connect (surface, "compute-size", G_CALLBACK (toplevel_compute_size), widget);
index 06a9f0f06a6e08cb24702d882995c61459f7d140..077d16136b767eff72d304e7b18d1131fa98ad3d 100644 (file)
@@ -4531,8 +4531,6 @@ surface_state_callback (GdkSurface  *window,
 
   new_state = gdk_toplevel_get_state (GDK_TOPLEVEL (window));
   msg = g_strconcat ((const char *)g_object_get_data (G_OBJECT (label), "title"), ": ",
-                     (new_state & GDK_TOPLEVEL_STATE_WITHDRAWN) ?
-                     "withdrawn" : "not withdrawn", ", ",
                      (new_state & GDK_TOPLEVEL_STATE_MINIMIZED) ?
                      "minimized" : "not minimized", ", ",
                      (new_state & GDK_TOPLEVEL_STATE_STICKY) ?